|
|
|
|
|
|
|
If you declare the GetEnvironmentStrings function as returning a string, Visual Basic happily expects that the value will be a BSTR and loads it into one of its internal string variables. Unfortunately, this value is not a BSTR, so as soon as Visual Basic tries to access the data or free it, chances are pretty good you'll see a memory exception. |
|
|
|
|
|
|
|
|
The first step is to declare the resulting value as a Long. That will give you a pointer to the memory buffer, which you can then free with the FreeEnvironmentStrings function. |
|
|
|
|
|
|
|
|
But what do you do with the buffer? |
|
|
|
|
|
|
|
|
From the puzzle example, you already have code that can scan a string for NULL characters and add the strings into the list box. So your only problem is copying the string data from the environment buffer into a string. The RtlMoveMemory function can copy the memory, but before you can call it, you need to know the total length of the buffer up to the two NULL characters. |
|
|
|
|
|
|
|
|
The FindDoubleNull function shown in the revised EnvStr.vbp project (on the CD that comes with this book) shows one way of accomplishing this: |
|
|
|
|
|
|
|
|
' Find the number of bytes up to and including the double null
Private Function FindDoubleNull(ByVal Ptr As Long) As Long
Dim bytebuffer(1) As Byte
Dim offset As Long
If Ptr = 0 Then Exit Function ' Error
Do
Call RtlMoveMemory(bytebuffer(0), ByVal (offset + Ptr), 2)
If bytebuffer(0) = 0 And bytebuffer(1) = 0 Then
FindDoubleNull = offset + 2 ' Add the two null bytes to the count
Exit Function
End If
offset = offset + 1
Loop While True
End Function |
|
|
|
|
|
|
|
|
The function copies the data two bytes at a time into the bytebuffer array, increasing the source address by one each time. When it finds two consecutive null bytes, it exits the function and returns the total number of bytes from the start address up to (and including) the two NULL characters. The RtlMoveMemory function can now be used to copy the data from the buffer into a string that is preallocated to the desired length. Note how the destination specified in the RtlMoveMemory function passes both the string and buffer address variables ByVal. The Environment string is passed ByVal in order to handle the conversion from the VB string to a NULL-terminated C string (which is the format in the buffer). The EnvironmentBuffer variable is passed ByVal |
|
|
|
|
|